package com.stenio.fancat.service.baby;

import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stenio.fancat.domain.baby.BabyAccount;
import com.stenio.fancat.domain.baby.BabyIconImage;
import com.stenio.fancat.domain.baby.BabyPartner;
import com.stenio.fancat.domain.baby.BabyRelationship;
import com.stenio.fancat.domain.bo.BabyPartnerBO;
import com.stenio.fancat.domain.user.UserRelationship;
import com.stenio.fancat.domain.user.UserRelationshipFomId;
import com.stenio.fancat.domain.user.UserRelationshipName;
import com.stenio.fancat.exception.FanCatException;
import com.stenio.fancat.form.baby.BabyPartnerForm;
import com.stenio.fancat.mapper.baby.BabyAccountMapper;
import com.stenio.fancat.mapper.baby.BabyIconImageMapper;
import com.stenio.fancat.mapper.baby.BabyPartnerMapper;
import com.stenio.fancat.mapper.baby.BabyRelationshipMapper;
import com.stenio.fancat.mapper.user.*;
import com.stenio.fancat.service.wx.WxPushServiceQcl;
import com.stenio.fancat.util.DateUtil;
import com.stenio.fancat.util.RedisUtil;
import com.stenio.fancat.vo.BabyPartnerVO;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * baby关系信息类
 */
@Service
public class BabyPartnerService extends ServiceImpl<BabyPartnerMapper, BabyPartner> {

    @Autowired
    private BabyPartnerMapper babyPartnerMapper;

    @Autowired
    private BabyAccountMapper babyMapper;

    @Autowired
    private BabyIconImageMapper babyIconImageMapper;

    @Autowired
    private UserRelationshipMapper userRelationshipMapper;

    @Autowired
    private UserRelationshipCandyMapper userRelationshipCandyMapper;

    @Autowired
    private UserRelationshipLogMapper userRelationshipLogMapper;

    @Autowired
    private BabyRelationshipMapper babyRelationshipMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    @Autowired
    private UserRelationshipNameMapper userRelationshipNameMapper;

    @Autowired
    private UserRelationshipFomIdMapper userRelationshipFomIdMapper;

    @Autowired
    private WxPushServiceQcl wxPushServiceQcl;

    @Value("${babyPartners}")
    private String babyPartnersKey;

    @Value("${babyPartnersNumbers}")
    private String babyPartnersNumbersKey;

    @Value("${babyPartnersList}")
    private String babyPartnersListKey;

    @Value("${key}")
    private String babyKey;

    @Value("${partnerList}")
    private String partnerListKey;

    @Value("${partnerBehaviorList}")
    private String partnerBehaviorListKey;

    /**
     * 通用查询
     * 根据userId查询babyId  (走的是缓存 --- Redis)
     * @param userId
     * @return
     */
    public String selectBabyId(String userId){
        return babyRelationshipMapper.selectBabyByUid(userId).getBabyId();
    }

    /**
     * 查看宝宝伙伴
     * @param userId
     * @return
     */
    public List<BabyPartnerBO> selectPartners(String userId) throws FanCatException {

        if(null == userId){
            throw new FanCatException("参数异常");
        }

        //判断Redis中是否含有key
        String babyId = this.selectBabyId(userId);
        if(null != redisUtil.get(babyPartnersKey+babyId)){
            return (List<BabyPartnerBO>) redisUtil.get(babyPartnersKey+babyId);
        }

        //创建容器
        List<BabyPartnerBO> list = new ArrayList<>();

        BabyRelationship babyRelationship = babyRelationshipMapper.selectBabyByUid(userId);

        if(null == babyRelationship){
            throw new FanCatException("请立即绑定宝宝");
        }

        //查看和宝宝关联的宝宝
        List<BabyPartner> partnersList = babyPartnerMapper.selectBabyPartnerByBid(babyRelationship.getBabyId());

        if(partnersList.isEmpty()){
            throw new FanCatException("和任何baby没有关联");
        }

        partnersList.stream().forEach(partners -> {
            BabyPartnerBO babyPartnerBO = new BabyPartnerBO();
            //封装基本信息
            BabyAccount babyAccount = babyMapper.selectByBid(partners.getAssociatedBabyId());
            babyPartnerBO.setBabyName(babyAccount.getNickName());
            babyPartnerBO.setBabyId(babyAccount.getBabyId());
            //封装宝宝头像--->URL
            BabyIconImage babyIconImage = babyIconImageMapper.selectByBid(partners.getAssociatedBabyId());
            babyPartnerBO.setBabyIconUrl(babyIconImage.getImage());

            list.add(babyPartnerBO);
        });

        //存放Redis中
        redisUtil.set(babyPartnersKey+babyId,list);

        return list;
    }


    /**
     * 根据userId查询小伙伴总数
     * @param userId
     * @return
     */
    public Integer selectCounts(String userId) throws FanCatException {
        if(null == userId){
            throw new FanCatException("参数异常");
        }

        //判断Redis中是否含有key
        String babyId = this.selectBabyId(userId);
        if(null != redisUtil.get(babyPartnersNumbersKey+babyId)){
            return (Integer) redisUtil.get(babyPartnersNumbersKey+babyId);
        }

        Integer number = 0;

        BabyRelationship babyRelationship = babyRelationshipMapper.selectBabyByUid(userId);

        number = babyPartnerMapper.selectCountPartners(babyRelationship.getBabyId());

        //存放Redis中
        redisUtil.set(babyPartnersNumbersKey+babyId,number);

        return number;
    }

    /**
     * 邀请小伙伴进入伙伴圈  相当于邀请一个新用户的业务逻辑  从baby注册开始实现  在baby注册成功后调用这个接口
     * @param babyPartnerForm
     * @return
     */
    public Integer InvitePartner(BabyPartnerForm babyPartnerForm) throws FanCatException {
        if(null == babyPartnerForm){
            throw new FanCatException("参数异常");
        }

        String babyId = this.selectBabyId(babyPartnerForm.getUserId());
        String babyIdSec = this.selectBabyId(babyPartnerForm.getAssociatedUserId());
        if(null == babyIdSec){
            throw new FanCatException("该用户没有创建baby");
        }

        Integer number = 0;

        //查询两个user是否关联过
        BabyRelationship babyRelationship = babyRelationshipMapper.selectBabyByUid(babyPartnerForm.getUserId());
        BabyRelationship babyRelationship2 = babyRelationshipMapper.selectBabyByUid(babyPartnerForm.getAssociatedUserId());
        BabyPartner babyPartner = babyPartnerMapper.isInvitePartner(babyRelationship.getBabyId(),babyRelationship2.getBabyId());
        if(null != babyPartner || StringUtils.isNotBlank(babyPartner.toString())){
            throw new FanCatException("已经建立了伙伴关系");
        }

        //建立关系
        BabyPartner baby = new BabyPartner();
        baby.setAssociatedBabyId(babyRelationship2.getBabyId());
        baby.setBabyId(babyRelationship.getBabyId());
        Date date = new Date();
        baby.setCreateTime(date);
        baby.setUpdateTime(date);
        baby.setState(0);
        number = babyPartnerMapper.insert(baby);

        //邀请成功后推送微信模板消息
        String userId = babyPartnerForm.getUserId();
        UserRelationship userRelationship = userRelationshipMapper.selectUserInfoById(userId);
        String[] arr = new String[5];
        arr[0] = "有新小伙伴加入啦";
        arr[1] = "伙伴圈";
        arr[2] = DateUtil.format(date,"yyyy-MM-dd HH:mm:ss");
        UserRelationshipFomId userRelationshipFomId = userRelationshipFomIdMapper.selectFormIdByUid(userId);
        if(null != userRelationshipFomId){
            String formId = userRelationshipFomIdMapper.selectFormIdByUid(userId).getFormId();
            //推送通知
            wxPushServiceQcl.pushOneUser(userRelationship.getOpenId(),formId,"zT81v_RBlI92CY5fwQgKN_mU0dGA0-aPdqmUa5_2kYQ",arr);
            //修改这个formid的状态
            userRelationshipFomIdMapper.modifyFormIdByUid(userId,formId);
        }

        //操作Redis
        redisUtil.del(babyId+babyPartnersKey,babyPartnersNumbersKey+babyId,
                babyPartnersListKey+babyId,babyIdSec+babyPartnersKey,babyPartnersNumbersKey+babyIdSec,
                babyPartnersListKey+babyIdSec);

        //删除伙伴圈
        Set<String> keys = redisTemplate.keys(babyId + partnerListKey + "*");
        redisTemplate.delete(keys);
        Set<String> keysSec = redisTemplate.keys(babyIdSec + partnerListKey + "*");
        redisTemplate.delete(keysSec);
        //删除伙伴动态详情
        Set<String> parKeys = redisTemplate.keys(babyId +partnerBehaviorListKey +"*");
        redisTemplate.delete(parKeys);
        Set<String> parKeysSec = redisTemplate.keys(babyIdSec +partnerBehaviorListKey +"*");
        redisTemplate.delete(parKeysSec);

        return number;
    }

    /**
     * 被邀请小伙伴的页面   --->   宝宝昵称  关系名称
     * @param userId
     * @return
     */
    public BabyPartnerVO invitedPage(String userId) throws FanCatException {
        if(null == userId){
            throw new FanCatException("参数异常");
        }

        BabyPartnerVO babyPartnerVO = new BabyPartnerVO();
        //封装baby昵称
        BabyRelationship babyRelationship = babyRelationshipMapper.selectBabyByUid(userId);
        BabyAccount babyAccount = babyMapper.selectByBid(babyRelationship.getBabyId());
        babyPartnerVO.setNickName(babyAccount.getNickName());

        //封装关系名称
        UserRelationship userRelationship = userRelationshipMapper.selectUserInfoById(userId);
        UserRelationshipName userRelationshipName = userRelationshipNameMapper.selectName(userRelationship.getRelationship());
        babyPartnerVO.setRelationshipName(userRelationshipName.getRelationshipName());

        //邀请金额为500  后期为请求出的数据
        babyPartnerVO.setCandy(500);

        return babyPartnerVO;
    }

    /**
     *  领糖果币（candy）  如果领完变成已领取   button
     * @param babyPartnerForm
     * @return
     */
    @Transactional
    public Integer getCandy(BabyPartnerForm babyPartnerForm) throws FanCatException {
        if(null == babyPartnerForm){
            throw new FanCatException("参数异常");
        }
        //查询改user关联的baby
        String babyId = this.selectBabyId(babyPartnerForm.getUserId());

        Integer i = 0;
        BabyRelationship babyRelationship = babyRelationshipMapper.selectBabyByUid(babyPartnerForm.getUserId());
        //修改user的candyLog记录
        Integer candyFir = babyMapper.selectByBid(babyRelationship.getBabyId()).getSurplusCandy();
        int g = userRelationshipLogMapper.modifyCandy(500,babyPartnerForm.getUserId(),candyFir);
        //修改user的candy
        int a = userRelationshipCandyMapper.modifyCandy(500,babyPartnerForm.getUserId());
        //修改宝宝的candy
        int d = babyMapper.modifyCandy(500,babyRelationship.getBabyId());

        //修改领取candy的状态为 1
        int j = babyPartnerMapper.modifyState(babyRelationship.getBabyId(),babyPartnerForm.getAssociatedBabyId());
        if(a>0 && d>0 && g>0 && j>0){
            i = 1;
        }

        //操作Redis
        redisUtil.del(babyKey+babyId,babyPartnersListKey+babyId);

        return i;
    }


    /** 已经邀请到的小伙伴  ---   展示出全部
     * @param userId
     * @return
     */
    public List<BabyPartnerBO> selectPartnersList(String userId) throws FanCatException {
        if (null == userId) {
            throw new FanCatException("参数异常");
        }

        //判断Redis中是否含有key
        String babyId = this.selectBabyId(userId);
        if(null != redisUtil.get(babyPartnersListKey+babyId)){
            return (List<BabyPartnerBO>) redisUtil.get(babyPartnersListKey+babyId);
        }

        //创建容器
        List<BabyPartnerBO> list = new ArrayList<>();
        //查询baby关联的baby
        BabyRelationship babyRelationship = babyRelationshipMapper.selectBabyByUid(userId);
        List<BabyPartner> babyPartnerList = babyPartnerMapper.selectBabyPartnerByBid(babyRelationship.getBabyId());
        if(babyPartnerList.isEmpty()){
            throw new FanCatException("该baby下没有任何伙伴");
        }
        babyPartnerList.stream().forEach(bp -> {
            BabyPartnerBO babyAccountVO = new BabyPartnerBO();
            BabyAccount babyAccount = babyMapper.selectByBid(bp.getAssociatedBabyId());
            BabyIconImage babyIconImage = babyIconImageMapper.selectByBid(bp.getAssociatedBabyId());
            babyAccountVO.setBabyId(babyAccount.getBabyId());
            babyAccountVO.setBabyName(babyAccount.getNickName());
            babyAccountVO.setBabyIconUrl(babyIconImage.getImage());
            babyAccountVO.setState(bp.getState()); //如果是1展示为已经领取
            list.add(babyAccountVO);
        });

        //存放Redis中
        redisUtil.set(babyPartnersListKey+babyId,list);

        return list;
    }

    /**
     * 分享判断两个user的关系
     * @param userId
     * @param associatedUserId
     * @return
     * @throws FanCatException
     */
    public Integer judgeRelation(String userId,String associatedUserId) throws FanCatException {
        if (null == userId || null == associatedUserId){
            throw new FanCatException("参数异常");
        }

        Integer state = 0;
        //1. 亲人关系   2. 伙伴关系  3. 普通用户  4. 新用户
        String babyId = this.selectBabyId(userId);
        if(null == babyRelationshipMapper.selectBabyByUid(associatedUserId)){
            state = 4;  //此用户没有注册
            return state;

        }
        String babyIdSec = babyRelationshipMapper.selectBabyByUid(associatedUserId).getBabyId();
        if(babyId.equals(babyIdSec)){
            state = 1;  //1. 亲人关系
            return state;
        }
        //查询邀请人的baby伙伴列表
        List<BabyPartner> list = babyPartnerMapper.selectBabyPartnerByBid(babyId);
        if(null == list || list.isEmpty()){
            state = 3;
            return state;
        }
        for(int i=0;i<list.size();i++){
            if ((list.get(i).getBabyId().equals(babyIdSec)) || (list.get(i).getAssociatedBabyId().equals(babyIdSec))) {
                state = 2;
                break;
            }else{
                state = 3;
            }
        }
        return state;
    }

}
